package com.code.view.listeners;

import java.io.IOException;
import java.util.Hashtable;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

import com.code.generator.ExceputionUtils;
import com.code.generator.GeneratorTemplate;
import com.code.generator.builder.ClassBuilder;
import com.code.generator.builder.CommonBuilder;
import com.code.generator.builder.ControllerBuilder;
import com.code.generator.builder.EditPageBuilder;
import com.code.generator.builder.EntityBuilder;
import com.code.generator.builder.ListPageBuilder;
import com.code.generator.builder.SqlMapperBuilder;
import com.code.generator.entity.TableEntity;
import com.code.generator.service.TableInfoService;
import com.code.view.ViewConstant;
import com.code.view.ViewUtils;
import com.code.view.entity.HandlerVO;
import com.code.view.entity.TableItemControl;

import freemarker.template.Configuration;


/**
 * "执行"按钮事件，这里触发代码生成
 *
 *
 * @author 朱国军
 * @version 2015年3月9日 朱国军
 */
public class ExcuseMouseListener implements MouseListener {
    private HandlerVO handlerVO;
    private Table table;
    private Shell shell;
    private Hashtable<TableItem, TableItemControl> tableControls;

    private TableInfoService tableInfo;

    private Configuration cfg;


    /**
     * 构造函数
     *
     * @param handlerVO 生成代码需要的配置数据
     * @param table 表格
     * @param shell 显示页面
     * @param tableControls 表格控件
     */
    public ExcuseMouseListener(HandlerVO handlerVO, Table table, Shell shell, Hashtable<TableItem, TableItemControl> tableControls) {
        this.handlerVO = handlerVO;
        this.table = table;
        this.shell = shell;
        this.tableControls = tableControls;
        tableInfo = new TableInfoService();
        GeneratorTemplate genTemplate = new GeneratorTemplate();
        try {
            cfg = genTemplate.getTemplateConfig();
        } catch (IOException e) {
            showDetailDialog("初始化模版出错", (IStatus) e);
        }

    }


    @Override
    public void mouseDoubleClick(MouseEvent e) {

    }


    @Override
    public void mouseDown(MouseEvent e) {

    }


    @Override
    public void mouseUp(MouseEvent e) {
        // 先清空日志文件
        ExceputionUtils.clearLogFile();
        String validateResult = validateInput();
        if (StringUtils.isNotBlank(validateResult)) {
            showMessageDialog(validateResult);
        } else if (cfg == null) {
            showMessageDialog("初始化模版失败！");
        } else {
            if (handlerVO.getIsCreateCommon()) {
                CommonBuilder commonBuilder = new CommonBuilder();
                commonBuilder.builder(null, null, handlerVO, cfg);
            }
            for (int i = 0; i < table.getItemCount(); i++) {
                String result = "";
                TableItem item = table.getItem(i);
                TableItemControl controls = tableControls.get(item);
                String packagePath = controls.getClassPathText().getText();
                String tableName = controls.getTableNameText().getText();
                if (StringUtils.isNotBlank(tableName) && StringUtils.isNotBlank(packagePath)) {
                    TableEntity tableEntity = tableInfo.queryTableInfo(tableName, handlerVO);
                    if (tableEntity == null) {
                        result += "获取表结构失败;";
                    } else {
                        if (handlerVO.getIsCreateEntity()) {
                            EntityBuilder entityBuilder = new EntityBuilder();
                            boolean entityResult = entityBuilder.builder(tableEntity, packagePath, handlerVO, cfg);
                            if (!entityResult) {
                                result += "实体生成失败;";
                            }

                            SqlMapperBuilder sqlMapperBuilder = new SqlMapperBuilder();
                            boolean sqlMapperResult = sqlMapperBuilder.builder(tableEntity, packagePath, handlerVO, cfg);
                            if (!sqlMapperResult) {
                                result += "sql生成失败;";
                            }
                        }
                        if (handlerVO.getIsCreateService()) {
                            ClassBuilder classBuilder = new ClassBuilder();
                            boolean classResult = classBuilder.builder(tableEntity, packagePath, handlerVO, cfg);
                            if (!classResult) {
                                result += "service,dao生成失败;";
                            }
                        }
                        if (handlerVO.getIsCreatePage()) {
                            EditPageBuilder editPageBuilder = new EditPageBuilder();
                            boolean editResult = editPageBuilder.builder(tableEntity, packagePath, handlerVO, cfg);
                            if (!editResult) {
                                result += "编辑页面生成失败;";
                            }
                            ListPageBuilder listPageBuilder = new ListPageBuilder();
                            boolean listResult = listPageBuilder.builder(tableEntity, packagePath, handlerVO, cfg);
                            if (!listResult) {
                                result += "列表页面生成失败;";
                            }
                        }
                        if (handlerVO.getIsCreateController()) {
                            ControllerBuilder controllerBuilder = new ControllerBuilder();
                            boolean controllerResult = controllerBuilder.builder(tableEntity, packagePath, handlerVO, cfg);
                            if (!controllerResult) {
                                result += "Controller生成失败;";
                            }
                        }
                    }
                } else {
                    result += "校验失败：表名和包路径不能为空";
                }
                if (StringUtils.isBlank(result)) {
                    result = "成功";
                }
                updateTableItem(i, result);
            }
            table.setSize(table.computeSize(shell.getBounds().width - 60, table.getBounds().height - 21, true));
        }
    }


    private void showMessageDialog(String message) {
        MessageDialog messageDialog =
                new MessageDialog(shell, "警告", ViewUtils.getImage("codegenerator.bmp"), message, MessageDialog.WARNING,
                    new String[] { "确定" }, 1);
        messageDialog.open();
    }


    private void showDetailDialog(String message, IStatus detail) {
        ErrorDialog err = new ErrorDialog(shell, "错误", message, detail, IStatus.ERROR);
        err.open();
    }


    private String validateInput() {
        String result = "";
        if (StringUtils.isBlank(handlerVO.getCommonPackage())) {
            result += "common包路径不能为空,";
        }
        if (!(handlerVO.getIsCreateCommon() || handlerVO.getIsCreateEntity() || handlerVO.getIsCreateService())) {
            result += "要生成的文件不能为空,";
        }
        if (StringUtils.isBlank(handlerVO.getOutPutPath())) {
            result += "代码输出目录不能为空,";
        }
        if (handlerVO.getIsCreateEntity() || handlerVO.getIsCreateService()) {
            if (StringUtils.isBlank(handlerVO.getDbUserName())) {
                result += "数据库用户名不能为空,";
            }
            if (StringUtils.isBlank(handlerVO.getDbUrl())) {
                result += "数据库URL不能为空,";
            }
            if (StringUtils.isBlank(handlerVO.getDbDriver())) {
                result += "数据库驱动不能为空,";
            }
            if (StringUtils.isBlank(handlerVO.getEntitySuffix())) {
                result += "实体类后缀不能为空,";
            }
        }

        return result;

    }


    /**
     * 将每一行的执行结果显示在列表上
     *
     * @param i
     * @param result
     */
    private void updateTableItem(int index, String result) {
        table.getItem(index).setText(ViewConstant.RESULT_INDEX, result);
    }
}
